package com.newsnetwork.admin.controller;

import com.newsnetwork.admin.service.AdminUserService;
import com.newsnetwork.api.BaseController;
import com.newsnetwork.api.controller.admin.AdminMngControllerApi;
import com.newsnetwork.exception.GraceException;
import com.newsnetwork.grace.result.CommonJSONResult;
import com.newsnetwork.grace.result.ResponseStatusEnum;
import com.newsnetwork.pojo.AdminUser;
import com.newsnetwork.pojo.bo.AdminLoginBO;
import com.newsnetwork.pojo.bo.NewAdminBO;
import com.newsnetwork.utils.PagedGridResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.UUID;


/**
 * @author: HuangDekai
 * @date: 2022/11/7 10:59
 * @version: 1.0
 * @since: jdk8
 * @description: 管理员登录相关接口实现
 */
@RestController
public class AdminMngController extends BaseController implements AdminMngControllerApi {
    private static final Logger log = LoggerFactory.getLogger(AdminMngController.class);

    @Autowired
    private AdminUserService adminUserService;

    @Override
    public CommonJSONResult adminLogin(AdminLoginBO adminLoginBO,
                                       HttpServletRequest request,
                                       HttpServletResponse response) {
        // 查询用户信息
        AdminUser admin = adminUserService.queryAdminByUsername(adminLoginBO.getUsername());
        // admin 为空则登录失败
        if (admin == null) {
            return CommonJSONResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }
        // 判断密码是否匹配
        boolean isPwdMatch = BCrypt.checkpw(adminLoginBO.getPassword(), admin.getPassword());
        // 不匹配
        if (!isPwdMatch) {
            return  CommonJSONResult.errorCustom(ResponseStatusEnum.ADMIN_NOT_EXIT_ERROR);
        }
        // 匹配
        doLoginSetting(admin, request, response);
        return CommonJSONResult.ok();
    }

    @Override
    public CommonJSONResult adminIsExist(String username, HttpServletRequest request, HttpServletResponse response) {
        checkAdminIsExist(username);
        return CommonJSONResult.ok();
    }

    @Override
    public CommonJSONResult addNewAdmin(NewAdminBO newAdminBO, HttpServletRequest request, HttpServletResponse response) {
        // base64 不为空, 则代表人脸入库, 否则需要输入用户名和密码
        if (StringUtils.isBlank(newAdminBO.getImg64())) {
            if (StringUtils.isBlank(newAdminBO.getPassword())) {
                return CommonJSONResult.errorCustom(ResponseStatusEnum.ADMIN_USERNAME_NULL_ERROR);
            }
            if (StringUtils.isBlank(newAdminBO.getPassword())) {
                return CommonJSONResult.errorCustom(ResponseStatusEnum.ADMIN_PASSWORD_NULL_ERROR);
            }
        }
        // 密码不为空, 判断两次输入一致
        if (StringUtils.isNotBlank(newAdminBO.getPassword()) ||
            StringUtils.isNotBlank(newAdminBO.getConfirmPassword())) {
            // 不一致
            if (!newAdminBO.getPassword().equalsIgnoreCase(newAdminBO.getConfirmPassword())) {
                return CommonJSONResult.errorCustom(ResponseStatusEnum.ADMIN_PASSWORD_ERROR);
            }
        }
        // 校验 admin 用户名是否已经存在
        checkAdminIsExist(newAdminBO.getUsername());

        // 持久化新的 admin 的信息
        adminUserService.createAdminUser(newAdminBO);

        return CommonJSONResult.ok();
    }

    @Override
    public CommonJSONResult getAdminList(Integer page, Integer pageSize) {
        if (page == null) {
            page = COMMON_START_PAGE;
        }
        if (pageSize == null) {
            pageSize = COMMON_PAGE_SIZE;
        }

        PagedGridResult result = adminUserService.queryAdminList(page, pageSize);
        return CommonJSONResult.ok(result);
    }

    @Override
    public CommonJSONResult adminLogout(String adminId,
                                        HttpServletRequest request,
                                        HttpServletResponse response) {
        // 删除 redis 中的 admin token
        redisOperator.del(REDIS_ADMIN_TOKEN + ":" + adminId);

        // 清除 cookie 中相关配置
        setCookie(request, response, "atoken", "",COOKIE_DELETED);
        setCookie(request, response, "aid", "",COOKIE_DELETED);
        setCookie(request, response, "aname", "", COOKIE_DELETED);

        return CommonJSONResult.ok();
    }

    /**
     * 用于 admin 用户登录过后的基本信息设置 (将token放入redis, 将 token id name 放入 cookie)
     * @param admin admin 用户 pojo
     * @param request 请求
     * @param response 响应
     */
    private void doLoginSetting(AdminUser admin,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        // 保存 token 于 redis 中
        String token = UUID.randomUUID().toString();
        redisOperator.set(REDIS_ADMIN_TOKEN + ":" + admin.getId(), token);
        // 将 admin 的登录基本信息 放入 cookie
        setCookie(request, response, "atoken", token, COOKIE_MONTH);
        setCookie(request, response, "aid", admin.getId(), COOKIE_MONTH);
        setCookie(request, response, "aname", admin.getAdminName(), COOKIE_MONTH);
    }

    /**
     * 检查 admin 用户名是否存在, 存在, 抛出异常, 表明该用户已存在
     * @param username admin 用户名
     */
    private void checkAdminIsExist(String username) {
        AdminUser adminUser = adminUserService.queryAdminByUsername(username);

        if (adminUser != null) {
            GraceException.display(ResponseStatusEnum.ADMIN_USERNAME_EXIST_ERROR);
        }
    }
}
